import datetime
import inspect
import os
import threading
from _mainlib import ColorPrint
from threading import Thread


def Return_formatted_string(descript, level, name, Thread_name, time_, pid):
    match level:
        case 'DEBUG':
            LEVEL_FOR_COLOR = ColorPrint.Fore.WHITE
        case 'INFO':
            LEVEL_FOR_COLOR = ColorPrint.Fore.PURPLE
        case 'WARNING':
            LEVEL_FOR_COLOR = ColorPrint.Fore.YELLOW
        case 'ERROR':
            LEVEL_FOR_COLOR = ColorPrint.Fore.RED
        case _:
            LEVEL_FOR_COLOR = ColorPrint.Fore.WHITE
    return "[{}--{}/{}] | {} | {} => {}".format(
        ColorPrint.Return_CPStr(Thread_name, forecolor=ColorPrint.Fore.BLUE),
        ColorPrint.Return_CPStr(name, forecolor=ColorPrint.Fore.BLUE),
        ColorPrint.Return_CPStr(time_.strftime("%Y-%m-%d %H:%M:%S"), forecolor=ColorPrint.Fore.GREEN),
        ColorPrint.Return_CPStr(pid, forecolor=ColorPrint.Fore.CYAN),
        ColorPrint.Return_CPStr(level, forecolor=LEVEL_FOR_COLOR),
        ColorPrint.Return_CPStr(descript, forecolor=ColorPrint.Fore.WHITE))


def CommonPrintLog(*log_mark):
    string = Return_formatted_string(*log_mark)
    print(string)


class Logger(object):
    DEBUG = 0
    INFO = 1
    WARNING = 2
    ERROR = 3

    # __all__ = [
    #     # final
    #     'DEBUG', 'INFO', 'WARNING', 'ERROR',
    #
    #     # function
    #     '__init__',
    #     'PrintLog',
    #     'debug',
    #     'info',
    #     'warning',
    #     'error',
    #     'set_print_level'
    # ]

    def __init__(self,
                 command=None,
                 file=r'.\log\latest.log',
                 print_level=0):

        try:
            os.mkdir(os.path.dirname(file))
        except:
            pass
        if command is None:
            command = [CommonPrintLog]
        self.command = command
        # self.format = format_
        self.print_level = print_level
        self.Logs = []
        self.LOG_THREAD = Thread(target=self.PrintLog, name="LOG_THREAD")
        self.LOG_THREAD.start()

    def PrintLog(self):
        while True:
            while self.Logs:
                log = self.Logs.pop()
                for func in self.command:
                    func(*log)

    def CommitLog(self, descript, level, name, Thread_name, time_=None, pid=os.getpid()):
        if self.print_level > getattr(self, level):
            return
        if time_ is None:
            time_ = datetime.datetime.now()
        self.Logs.append([descript, level, name, Thread_name, time_, pid])

    def info(self, mes):
        name = inspect.stack()[1][3]
        self.CommitLog(mes, 'INFO', name, threading.current_thread().name)

    def warning(self, mes):
        name = inspect.stack()[1][3]
        self.CommitLog(mes, 'WARNING', name, threading.current_thread().name)

    def debug(self, mes):
        name = inspect.stack()[1][3]
        self.CommitLog(mes, 'DEBUG', name, threading.current_thread().name)

    def error(self, mes):
        name = inspect.stack()[1][3]
        self.CommitLog(mes, 'ERROR', name, threading.current_thread().name)

    def set_print_level(self, print_level):
        self.print_level = print_level


class StopPrinting:
    def __init__(self, LOGGER: Logger):
        self.LOGGER = LOGGER
        self.old_print_level = self.LOGGER.print_level
        self.LOGGER.set_print_level(Logger.ERROR)

    def __enter__(self):
        return self.LOGGER

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.LOGGER.set_print_level(self.old_print_level)


LOGGER = Logger(print_level=Logger.INFO)

if __name__ == '__main__':
    LOGGER.info("j")
